<template>
  <view class="fu-tabs" :class="[
    `fu-tabs--${type}`,
    {
      'fu-tabs--scroll': scroll && isScroll,
      'fu-tabs--fixed': !scroll
    }
  ]">
    <scroll-view 
      class="fu-tabs__scroll" 
      :scroll-x="scroll && isScroll"
      :scroll-left="scrollLeft"
      :scroll-with-animation="true"
    >
      <view class="fu-tabs__wrapper">
        <!-- 卡片类型的背景动画块 -->
        <view 
          v-if="type === 'card'"
          class="fu-tabs__card-block"
          :style="{
            transform: `translateX(${cardLeft}px)`,
            width: `${cardWidth}px`
          }"
        ></view>
        
        <view 
          v-for="(item, index) in list"
          :key="index"
          class="fu-tabs__item"
          :class="{
            'is-active': currentValue === item.name,
            'is-disabled': item.disabled
          }"
          :style="[getItemStyle(item)]"
          @tap="onTabClick(item)"
        >
          {{ item.label }}
        </view>
        <!-- 非卡片类型的底部滑块 -->
        <view 
          v-if="showBar && type !== 'card'"
          class="fu-tabs__line" 
          :style="{
            transform: `translateX(${barLeft}px)`,
            width: `${barWidth}px`,
            backgroundColor: activeColor,
            height: `${barHeight}rpx`
          }"
        ></view>
      </view>
    </scroll-view>
  </view>
</template>

<script>
/**
 * @description tabs标签页组件
 * @property {Array} list 标签列表，格式：[{name: 1, label: '标签1', disabled: false}]
 * @property {String/Number} value/v-model 当前选中的标签的值
 * @property {Boolean} scroll 是否可以滚动，默认true
 * @property {String} type 样式类型，可选值为 default/card/button
 * @property {Boolean} show-bar 是否显示底部条
 * @property {Number} bar-width 底部条宽度，单位px
 * @property {Number} bar-height 底部条高度，单位rpx
 * @property {String} active-color 选中项的主题颜色
 * @property {String} inactive-color 未选中项的颜色
 * @property {String/Number} font-size 字体大小，单位rpx
 * @property {Boolean} bold 选中项是否加粗
 * @event {Function} change 点击标签时触发
 */
export default {
  name: 'FuTabs',

  props: {
    // 标签列表
    list: {
      type: Array,
      default: () => []
    },
    // v-model双向绑定的值
    value: {
      type: [String, Number],
      default: ''
    },
    // 组件类型
    type: {
      type: String,
      default: 'default'
    },
    // 是否显示底部条
    showBar: {
      type: Boolean,
      default: true
    },
    // 底部条宽度
    barWidth: {
      type: [String, Number],
      default: 40
    },
    // 底部条高度
    barHeight: {
      type: [String, Number],
      default: 6
    },
    // 选中项的主题颜色
    activeColor: {
      type: String,
      default: '#2979ff'
    },
    // 未选中项的颜色
    inactiveColor: {
      type: String,
      default: '#303133'
    },
    // 字体大小
    fontSize: {
      type: [String, Number],
      default: 28
    },
    // 选中项字体是否加粗
    bold: {
      type: Boolean,
      default: true
    },
    // 是否可以滚动
    scroll: {
      type: Boolean,
      default: true
    }
  },

  data() {
    return {
      currentValue: this.value || (this.list[0] && this.list[0].name) || '',
      barLeft: 0,
      scrollLeft: 0,
      isScroll: false,
      cardLeft: 0,
      cardWidth: 0
    }
  },

  watch: {
    value(val) {
      if (val !== this.currentValue) {
        this.currentValue = val
        this.$nextTick(() => {
          this.updatePosition()
        })
      }
    },
    
    list: {
      handler() {
        if (!this.currentValue && this.list.length) {
          this.currentValue = this.list[0].name
        }
        this.$nextTick(() => {
          this.init()
        })
      },
      immediate: true
    }
  },

  mounted() {
    this.init()
  },

  methods: {
    init() {
      setTimeout(() => {
        this.updatePosition()
      }, 100)
    },

    updatePosition() {
      const query = uni.createSelectorQuery().in(this)
      query.select('.fu-tabs__scroll').boundingClientRect()
      query.selectAll('.fu-tabs__item').boundingClientRect()
      query.exec(([scrollRect, itemRects]) => {
        if (Array.isArray(itemRects) && itemRects.length && scrollRect) {
          // 判断是否需要滚动
          const totalWidth = itemRects.reduce((width, rect) => width + rect.width, 0)
          this.isScroll = this.scroll && totalWidth > scrollRect.width
          
          // 获取当前选中项的位置
          const index = this.list.findIndex(item => item.name === this.currentValue)
          if (index > -1) {
            const currentRect = itemRects[index]
            const itemLeft = currentRect.left - scrollRect.left
            const itemWidth = currentRect.width
            
            if (this.isScroll) {
              // 计算目标滚动位置
              const targetLeft = Math.max(0, itemLeft - (scrollRect.width - itemWidth) / 2)
              
              // 更新滑块位置
              if (this.type === 'card') {
                this.cardLeft = itemLeft
                this.cardWidth = itemWidth
              } else {
                this.barLeft = itemLeft + (itemWidth - this.barWidth) / 2
              }
              
              // 设置滚动位置
              if (this.scrollLeft !== targetLeft) {
                this.scrollLeft = targetLeft
              }
            } else {
              // 非滚动模式
              if (this.type === 'card') {
                this.cardLeft = itemLeft
                this.cardWidth = itemWidth
              } else {
                this.barLeft = itemLeft + (itemWidth - this.barWidth) / 2
              }
            }
          }
        }
      })
    },

    onTabClick(item) {
      if (item.disabled) {
        this.$emit('disabled', item)
        return
      }
      if (this.currentValue !== item.name) {
        this.currentValue = item.name
        this.$emit('input', item.name)
        this.$emit('change', item.name)
        
        // 延迟更新位置，等待 DOM 更新
        setTimeout(() => {
          this.updatePosition()
        }, 50)
      }
    },

    getItemStyle(item) {
      const style = {
        fontSize: `${this.fontSize}rpx`
      }
      
      if (!this.scroll) {
        style.flex = 1
      }
      
      if (this.currentValue === item.name) {
        style.color = this.activeColor
        if (this.bold) style.fontWeight = 'bold'
      } else {
        style.color = item.disabled ? '#c8c9cc' : this.inactiveColor
      }
      
      return style
    }
  }
}
</script>

<style lang="scss">
.fu-tabs {
  width: 100%;
  height: 80rpx;
  position: relative;
  background: #fff;
  
  // 卡片风格
  &--card {
    padding: 4rpx;
    background: #f5f7fa;
    border-radius: 8rpx;
    height: 72rpx;
    
    .fu-tabs__wrapper {
      height: 100%;
      position: relative;
      justify-content: normal!important;
    }
    
    .fu-tabs__card-block {
      position: absolute;
      height: 64rpx;
      background: #fff;
      border-radius: 6rpx;
      transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
      box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.08);
      z-index: 0;
      will-change: transform;
    }
    
    .fu-tabs__item {
      background: transparent;
      margin: 0 4rpx;
      padding: 0 24rpx;
      height: 64rpx;
      border-radius: 6rpx;
      font-size: 28rpx;
      color: #666;
      transition: all 0.25s ease-in-out;
      position: relative;
      z-index: 1;
      
      &:first-child {
        margin-left: 0;
      }
      
      &:last-child {
        margin-right: 0;
      }
      
      &.is-active {
        color: #2979ff;
        font-weight: 500;
      }
      
      &.is-disabled {
        color: #c8c9cc;
        cursor: not-allowed;
      }
    }
  }
  
  &--scroll {
    .fu-tabs__wrapper {
      white-space: nowrap;
      display: inline-block;
      min-width: 100%;
    }
  }
  
  &--fixed {
    .fu-tabs__wrapper {
      display: flex;
      justify-content: space-around;
    }
    
    .fu-tabs__item {
      flex: 1;
    }
  }
  
  &__scroll {
    width: 100%;
    height: 100%;
    overflow: hidden;
    
    // 隐藏滚动条
    ::-webkit-scrollbar {
      display: none;
      width: 0 !important;
      height: 0 !important;
      -webkit-appearance: none;
      background: transparent;
    }
    
    // 兼容 iOS
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  
  &__wrapper {
    position: relative;
    height: 100%;
    display: flex;
    align-items: center;
  }
  
  &__item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 0 30rpx;
    position: relative;
    transition: all 0.3s;
    flex-shrink: 0;
    
    &.is-disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
  }
  
  &__line {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 4rpx;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    border-radius: 100rpx;
    z-index: 1;
    pointer-events: none;
    will-change: transform;
  }
}
</style> 